ProcDoggie is a full blown application that demonstrates a variety of Process Manager-related techniques, including:
1. Getting a list of running processes
2. Getting information about a running process
3. Launching a processes, with and without opening documents
Introduction
Description
System Software 7.0 includes the Process Manager which allows programs to launch applications and desk accessories, and to get information about other applications and desk accessores that have been launched (both generically known as “processes”).
ProcDoggie is a sample application that demonstrates typical uses of the Process Manager. When ProcDoggie is launched, a window appears which displays a list of all processes that are active on the machine that ProcDoggie is running on. I call this the “Process List window.” The user can click on any of the processes in the Process List window to select that process, and can shift-click or command-click to select more than one process.
When one or more processes are selected, the user can either view information about those processes, bring those processes to the front, or terminate those processes. Of course, only one process can be at the front at any time, so each of the selected processes are brought to the front in turn.
When the user chooses to view information about the selected processes, a window which I call the “Process Info window” is opened for each of the selected processes. This window displays information about the type and creator of the process, whether the process is an application or desk accessory, how large its partition is, how much memory it’s using, and the status of the flags in its SIZE resource.
The File menu contains commands that the user can use to launch applications and desk accessories. The user can launch an application or desk accessory so that it becomes the front process, or the user can launch an application so that it becomes a background process, or the user can launch an application or desk accessory and then terminate ProcDoggie.
Additionally, the user can choose whether a simple launch is performed or whether the launch should specify documents to be opened or printed by the launched application.
Coverage
This sample code additionally shows:
• simple use of AEInteractWithUser
• MacApp-like menu enabling and disabling
• use of the International Utilities to display formatted numbers
• writing a simple single-line replacement for TextBox
• how to read a DITL resource
• use of courteous colors in a palette
• simple use of MakeRGBPat to display proper colors regardless of the depth of a screen
• simple cases of taking advantage of Color QuickDraw while still running on classic QuickDraw machines
• sending 'oapp' and 'quit' AppleEvents to other applications running on the same machine
• accepting 'quit' AppleEvents
• simple use of the List Manager
• writing a custom LDEF
• using a grow-zone proc to handle low-memory situations
Caveats
Text drawing should be done using TruncString to ensure that the text fits in the designated cell and, if it doesn’t, to truncate it in an international friendly fashion.
ProcDoggie does a “roll your own dialog manager”. The code for this is described in “UDialogUtils.p”. Although this is a noble goal, the implementation is flawed. See the comment in ”UDialogUtils.p” (especially the implementation comment for “InstallDialogItems”) for the reason why.
There’s still a lot of code that I’d like to tidy up and bring into my own style in this sample, but I’ve decided to not do that under the maxim “If it works, don’t mess with it.” — Quinn, 17 Mar 1997
Details
Building ProcDoggie
ProcDoggie was built using Metrowerks CodeWarrior Pro 1’s Pascal compiler. To build ProcDoggie, simply open the “ProcDoggie.µ” project and choose Make from the Project menu.
Packing List
The following files are included in the distribution:
• Read Me About ProcDoggie — This document.
• ProcDoggie.µ — The project to build the 68K, PPC and FAT versions.
• ProcDoggie — The compiled FAT application.
• ProcDoggie.p — The main line of the application.
• UEvents.p — The event handling code for the application.
• UMenuHandler.p — The menu handling code for the application
• UProcessGuts.p — The core code to handle the process list window and the process info windows.
• UProcessLDEF.p — The LDEF code for the process list window.
• UProcessUtils.p — Some Process Manager utilities.
• UGlobals.p — Application globals and utility routines.
• UDialogUtils.p — A “roll your own dialog manager” module. See the Caveats sections of this document for why this is not recommended.
• UEmergMem.p — A memory library for wrapping the system Memory Manager to avoid very low memory conditions.
• ProcDoggie.rsrc — The bulk of the application’s resources.
• ProcDoggie.r — A special 'DITL' resource. This exists because the ResEdit 'DITL' editor won’t edit this special 'DITL' because of it’s weird format. See the Caveats sections of this document for an explanation.
• StubLDEF — A tiny LDEF that simply calls through the ListHandle’s refCon field. Using this allows the real LDEF code to reside in the application, which is useful for the PPC port and aids in debugging.
End Matter
Credits
If you find any problems with this sample, mail <DevSupport@apple.com> with “Attn: Quinn” as the first line of your mail and I’ll try to fix them up.
The sample was originally written by Forrest Tanaka.
Thanks to Jeff Hokit for inspiring the name.
Significant maintenance (including the PowerPC conversion) was done by Quinn “The Eskimo!”.
Share and Enjoy
Quinn “The Eskimo!”
Apple Developer Technical Support
Networking, Communications, Hardware
[And Pascal guru, which is why I’m maintaining this sample (–: ]
Version History
Version 1.0a1
Date unknown by Forrest Tanaka
This version had all features except the ability to terminate processes implemented, but very little of the user interface was implemented. Never released to AppleLink
Version 1.0a2
Date unknown by Forrest Tanaka
The same features were there, but the user interface was much more complete. Never released to AppleLink.
Version 1.0a3
November 3, 1990 by Forrest Tanaka
This version has features as described above with the exception of being able to terminate selected processes. Readied for release on AppleLink on November 3.
Version 1.0a4
No date
This version never existed. I renumbered everything as 1.0a5 by mistake.
Version 1.0a5
December 18, 1990 by Forrest Tanaka
• The ability to terminate selected processes has been added.
• Error-checking and recovery has been massively improved. In theory, ProcDoggie should never bomb with any kind of error.
• High-level events are now accepted, though only 'quit' AppleEvents are handled because ProcDoggie has no documents.
• Previously, ProcDoggie didn’t send 'oapp' events to applications which were high-level event aware, nor did it properly send 'odoc' events to those applications. These problems have been fixed.
• The Utilities sample code unit is no longer used. All the Utilities functionality I was using has been absorbed into ProcDoggie.
• If an alert is about to be presented while ProcDoggie is in the back- ground, the Notification Manager is used to alert the user that ProcDoggie has something to say.
• Readied for release on AppleLink on December 18.
Version 1.0a6
February 6, 1991 by Forrest Tanaka
• DrawMenuBar bombs after I send a quit event to MacPaint (and a few other applications) and then delete the selected row in the process list. So I changed the DrawMenuBar call to InvalMenuBar and it seems to work around the problem. I don’t know why DrawMenuBar has a problem in this specific case involving the Menu, AppleEvent, and List managers.
• In InstallDialogItems, I was calling GetIndString with an index of 0 if there isn’t a specified font name. GetIndString bombs under 7.0b4 if you do that so now I check for this case.
• My LDEF was drawing a cell even if the specified length of the cell’s data was 0. That caused garbage to appear in new cells until I set a real value in the cell. Now, I don’t draw the cell if the length of the cell’s data is 0.
• I think my LDEF now draws the process names from right aligned on a bidirectional script system. Since I don’t have a bidirectional 7.0 script system, I can’t test this yet.
• Because of a bug in file filtering in 7.0b1, I used SFGetFile instead of StandardGetFile. With 7.0b1 dead and buried, I’m now using StandardGetFile.
• Dammit Jim! I’m a C programmer, not a Pascal programmer. I turned off range checking in all the source code files.
• I eliminated the UWindowHandler unit and moved the routines that were in it to ProcDoggie.p and the UGlobals unit.
Version 2.1b1
18 March 1997, by Quinn “The Eskimo!”
• The read me described version 1.0a6 as the latest version, but the application had version 2.0 in its 'vers' resource. I’ve upgrade to 2.1 to avoid any confusion.
• Converted to Metrowerks Pascal.
• Removed ‘include file madness’ that was an artifact of the MPW Pascal environment. Halved the number of source files. Yippee!
• Got rid of “ProcDoggie.r”, which only included a single DITL resource that I rolled into “ProcDoggie.rsrc”.
• Made the AppleEvent handlers take VAR AppleEvents in preparation for PPC conversion.
• Turned on all compiler warnings and eliminated any problems thereby caused.
• Rationalise list of units each unit USES.
• Install standard DTS disclaimer in all source files..
• TerminateProcess was not setting the error result for the noErr case.
• Only unhilite a menu if we’re not quitting.
• Rolled “ProcDoggie.r” back into the source and put a comment in it that explains why it’s needed.
• Changed the number format resource from 'NUMF' ID=0 to 'FMAT' ID=128. The type change allows me to edit it using Michael Hecht’s way cool ResEdit editor for 'FMAT' resources. The ID change is to bring the resource into the application resource ID range.
• Turned range checking back on; we’ll see what errors it spits out.
• Renamed “%A5Init” (a serious MPW-ism) segment to “Startup”.
• Checked for and eliminated other weird compiler directives.
• Conditionalised UnloadSeg call for classic runtime.
• Added a Close menu command because testing it without one was driving me nuts!
• Change ProcessListInfoRec to hold a Str255 for the process name, a Str31 is definitely not enough!
• Reworked NotifyAlert to use AEInteractWithUser.
• Changed all BlockMove's to BlockMoveData's.
• We now check for System 7 at startup and bail out if we don’t have it.
• Confirmed why can’t DoBringProcessToFront yank ProcDoggie to front. See the comment for the implementation of DoBringProcessToFront in “UProcessGuts.p”.
• Wrote a single number to string routine (MyNumberString) which is now called by both “SetUpProcessInfoItems” and “IdleProcessInfoWindow”. The old code had two identical copies of the same routine.
• Ran it under Appearance (Mac OS 8.0a3) to check that the Palette Manager code looks OK there.
• Checked the standard file filter routine for “opening already open file” problem -- did some research and the current code will work fine is all cirumstances because it opens the file read-only.
• Process info window now displays new process flags, namely modeUseTextEditServices and modeDisplayManagerAware.
• Changed idle function in NotifyAlert to handle update events. Doing this involved taking the event handling code out of “ProcDoggie.p” into “UEvents.p” so that “UGlobals.p” can import the DoEvent routine.
• The possibility of user interaction being denied now means that NotifyAlert (and the other alert functions that call it) must return an error.
• PPC port — add lots of UPPs.
• PPC port — rationalised handling of floating point numbers when calling ExtendedToString
• PPC port — converted LDEF to VAR cellRect: Rect to avoid crashing
• Fixed an update bug introduced when implementing MyNumberString.
Version 2.1b2
28 Oct 1997, by Quinn “The Eskimo!”
• SetGrowZone(gzUPP) is much better than SetGrowZone(@gzUPP). It seems that the grow zone routine had never been tested, because this bug would have caused it to crash every time. I found this by testing on Mac OS 8.0 + Japanese Language Kit 1.2 + Language Kit Updater, which seems to call the grow zone routine on a regular basis, even if there's plenty of RAM in the heap.